package com.syyc.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;

public class MyBatisUtils {
    //声明一个工厂对象
    private static SqlSessionFactory sqlSessionFactory;

    //通过ThreadLocal存储SqlSession，为了保证线程安全
    public static final ThreadLocal<SqlSession> THREAD_LOCAL = new ThreadLocal<>();

    //通过静态代码块加载配置文件并获取工厂对象（只需要加载一次）
    static {
        try {
            //读取配置文件
            Reader resourceAsReader = Resources.getResourceAsReader("mybatis-config.xml");

            //获取工厂对象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得连接（从ThreadLocal中获得档期那线程sqlsession）
     * @return
     */
    private static SqlSession openSession(){
        //首先通过ThreadLocal获取SqlSession
        SqlSession sqlSession = THREAD_LOCAL.get();

        if (sqlSession == null){
            //从工厂对象中获取连接
            SqlSession sqlSession1 = sqlSessionFactory.openSession();

            //将连接存入THREAD_LOCAL
            THREAD_LOCAL.set(sqlSession1);

            return sqlSession1;
        }

        return sqlSession;
    }

    /**
     * 释放连接（释放当前线程中的sqlsession
     */
    public static void close() {
        //从THREAD_LOCAL中获取连接
        SqlSession sqlSession = THREAD_LOCAL.get();

        //关闭连接
        sqlSession.close();

        //从THREAD_LOCAL中移除连接
        THREAD_LOCAL.remove();
    }

    /**
     * 提交事务（提交当前线程中的sqlsession所管理得事务）
     */
    public static void commit(){
        //获取连接
        SqlSession sqlSession = openSession();

        //提交事务
        sqlSession.commit();

        //关闭资源
        //close();
    }

    /**
     * 回滚事务
     */
    public static void rollback(){
        //获取连接
        SqlSession sqlSession = openSession();

        //回滚事务
        sqlSession.rollback();

        //关闭资源
        close();
    }

    /**
     * 获取代理对象
     */
    public static <T> T getMapper(Class<T> tClass) {
        //获取连接
        SqlSession sqlSession = openSession();

        //获取接口代理对象
        return sqlSession.getMapper(tClass);
    }

}
